﻿/*
Copyright (c) 2010 Vratislav Cermak (vratacermak@gmail.com)
 
This file is part of TeachMe Project. See http://code.google.com/p/teach-me for more information.
 
TeachMe is an open source project. Using of TeachMe is free of charge.
It is distributed under GNU General Public License version 3 (GPLv3).
GPLv3 can be found at http://www.gnu.org/licenses/gpl.html.
 
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;

namespace TeachMe.Application.InlineTests
{
    public class Runner
    {
        public static void Test(Type type)
        {
            MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);

            foreach (MethodInfo method in methods)
            {
                object[] attributes = method.GetCustomAttributes(typeof(TestAttribute), true);

                if (attributes == null || attributes.Length == 0)
                {
                    continue;
                }

                Logging.Debug(typeof(Runner), String.Format("Testing method '{0}'.", method));

                foreach (TestAttribute attribute in attributes)
                {
                    string description = CreateDescription(attribute);

                    Logging.Debug(typeof(Runner), description);

                    if (!method.Invoke(null, (attribute).Parameters).Equals(attribute.Result))
                    {
                        Debug.Assert(false, "Test failed.", description);

                        Logging.Error(typeof(Runner), "Test failed.");
                    }
                    else
                    {
                        Logging.Debug(typeof(Runner), "Test passed.");
                    }
                }
            }
        }

        public static void Test(Assembly assembly)
        {
            Type[] types = assembly.GetTypes();

            foreach (Type type in types)
            {
                Test(type);
            }
        }

        private static string CreateDescription(TestAttribute attribute)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append(String.Format("Result value '{0}' is expected for parameters ", attribute.Result));

            for (int idx = 0; idx < attribute.Parameters.Length; idx++)
            {
                if (attribute.Parameters[idx] == null || String.IsNullOrEmpty(attribute.Parameters[idx].ToString()))
                {
                    builder.Append("'(empty)'");
                }
                else
                {
                    builder.Append(String.Format("'{0}'", attribute.Parameters[idx]));
                }

                if (idx < attribute.Parameters.Length - 1)
                {
                    builder.Append(", ");
                }
                else
                {
                    builder.Append(".");
                }
            }

            return builder.ToString();
        }
    }
}
